package server;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ReadXMLUtil {

    public ReadXMLUtil(List<Map<String, Host>> serverList) {
        ServerList = serverList;
    }

    private List<Map<String, Host>> ServerList;

    /**
     * 加载server.xml，解析并初始化各项目的servlet
     */
    public void loadServlet() {
        InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("server.xml");
        SAXReader saxReader = new SAXReader();

        try {
            Document document = saxReader.read(resourceAsStream);
            Element rootElement = document.getRootElement();

            List<Element> selectNodes = rootElement.selectNodes("//Server");
            for (int i = 0; i < selectNodes.size(); i++) {
                Element element =  selectNodes.get(i);
                List<Element> ServiceNodes = element.selectNodes("//Service");
                Map<String, Host> serviceMap = new HashMap<String,Host>();
                //遍历service
                for (Element service:ServiceNodes) {
                    //获取监听端口
                    Element connectorNode = (Element)service.selectSingleNode("//Connector");
                    String port = connectorNode.attributeValue("port");

                    Element EngineNode = (Element)service.selectSingleNode("//Engine");
                    List<Element> HostNodes = EngineNode.selectNodes("//Host");

                    //service和engine同级处理，遍历host
                    Map<String,Context> contextMap = new HashMap<String,Context>();
                    for (Element hostNo:HostNodes) {
                        //获取每个host的名称和项目路径
                        String hostName = hostNo.attributeValue("name");
                        String appBase = hostNo.attributeValue("appBase");
                        File file = new File(appBase);
                        if(!file.exists()||file.list()==null){
                            break;
                        }
                        String[] list = file.list();
                        //遍历子文件夹，既实际的项目列表
                        for(String path:list){
                            //将项目封装成context，并保存入map
                            contextMap.put(path,loadContextServlet(appBase+"\\"+path+"\\"));
                        }
                        serviceMap.put((hostName+":"+port).trim(),new Host(contextMap));
                    }
                }
                ServerList.add(serviceMap);
            }
        } catch (DocumentException e) {
            e.printStackTrace();
        }
    }

    private Context loadContextServlet(String path) {
        String webPath = path+"web.xml";
        if(!(new File(webPath).exists())){
            System.out.println("未找到"+path+"web.xml");
            return null;
        }
        try {
            InputStream resourceAsStream = new FileInputStream(webPath);
            SAXReader saxReader = new SAXReader();

            Document document = saxReader.read(resourceAsStream);
            Element rootElement = document.getRootElement();

            List<Element> selectNodes = rootElement.selectNodes("//servlet");
            Map<String,Wrapper> wrapperMap = new HashMap<String,Wrapper>();
            for (int i = 0; i < selectNodes.size(); i++) {
                Element element =  selectNodes.get(i);
                // <servlet-name>lagou</servlet-name>
                Element servletnameElement = (Element) element.selectSingleNode("servlet-name");
                String servletName = servletnameElement.getStringValue();
                // <servlet-class>server.LagouServlet</servlet-class>
                Element servletclassElement = (Element) element.selectSingleNode("servlet-class");
                String servletClassStr = servletclassElement.getStringValue();
                String classStr = path+servletClassStr.replaceAll("\\.","\\\\")+".class";
                //加载这个class文件
                MyClassLoader myClassLoader = new MyClassLoader(path);
                Class<?> servletClass = myClassLoader.loadClass(servletClassStr);
                // 根据servlet-name的值找到url-pattern
                Element servletMapping = (Element) rootElement.selectSingleNode("/web-app/servlet-mapping[servlet-name='" + servletName + "']");
                // /lagou
                String urlPattern = servletMapping.selectSingleNode("url-pattern").getStringValue();
                HttpServlet servlet = (HttpServlet)servletClass.newInstance();
                //将最后获得的servlet存入wrapper，并且存入wrapperMap
                wrapperMap.put(urlPattern, new Wrapper(servlet));
            }
            return new Context(wrapperMap);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
